<?php


namespace models\Business;


use models\DAO\AlibabacategoryModel;
use models\Exception\Business\AlibabacategoryException;
use models\Exception\Business\AlibabaproductException;
use models\Exception\DAO\ModelDriverException;
use models\Exception\DAO\ModelException;
use models\Exception\DAO\ModelReflectionException;
use models\Exception\DAO\ModelSqlException;
use models\Exception\Service\ServiceException;
use models\Exception\Transformer\TransformerException;
use models\Service\AlibabacategoryService;
use Yaf\Registry;

class AlibabaCategory
{
    /**
     * 根据非叶级类目获取其父类下的叶级类目编号
     * @param $parent_id
     * @return array
     * @throws AlibabacategoryException
     * @throws ModelSqlException
     */
    static public function getAllLeafCategoryByParentId($parent_id) {
        $sql = "SELECT DATA.id FROM " .
            "(SELECT @ids AS _ids, (SELECT @ids := GROUP_CONCAT(id) FROM alibabacategory WHERE FIND_IN_SET(parent , @ids)) AS cids, @l := @l + 1 AS LEVEL ".
            "FROM alibabacategory, (SELECT @ids := '" . $parent_id . "' , @l := 0) AS b WHERE @ids IS NOT NULL) AS id, alibabacategory AS DATA ".
            "WHERE FIND_IN_SET(DATA .id , _ids) and publishing = 1 ORDER BY LEVEL, id";

        $alibaba_category_conn = AlibabacategoryModel::getInstance()->getConn();
        $alibaba_category_conn->query($sql);
        $category_arr = $alibaba_category_conn->fetchAll($sql);
        if (empty($category_arr))
            throw new AlibabacategoryException(AlibabaproductException::ALIBABAPRODUCT_IS_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_IS_NOT_EXISTS_NO);

        return array_column($category_arr, 'id');
    }

    /**
     * 根据子类获取全部父类
     * @param $sub_category_id
     * @return mixed
     * @throws AlibabacategoryException
     * @throws ModelSqlException
     */
    static public function getAllParentsByParentId($sub_category_id) {
        $sql = "SELECT T2.id, T2.name,T1.lvl FROM " .
            "(SELECT @r AS _id, @STOP :=@STOP + IF(@r = 2 , 1 ,@STOP) AS STOP, ".
            "(SELECT @r := parent FROM alibabacategory WHERE id = _id) AS parent , @l := @l + 1 AS lvl FROM " .
            "(SELECT @r := " . $sub_category_id . " , @l := 0 , @STOP := 0) vars, alibabacategory h WHERE @STOP < 1) T1 ".
            "JOIN alibabacategory T2 ON T1._id = T2.id ORDER BY T1.lvl DESC";

        $alibaba_category_conn = AlibabacategoryModel::getInstance()->getConn();
        $alibaba_category_conn->query($sql);
        $category_arr = $alibaba_category_conn->fetchAll($sql);

        if (empty($category_arr))
            throw new AlibabacategoryException(AlibabaproductException::ALIBABAPRODUCT_IS_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_IS_NOT_EXISTS_NO);

        return $category_arr;
    }

    /**
     * @param array $module_list
     * @return array
     */
    static public function getCategoriesByModules($module_list = []) {

        try {
            $categories = $categories_name_id_arr = [];
            $category_id_arr = array_column($module_list['data'], 'category_id');
            $category_id_arr = array_filter($category_id_arr);

            if (count($category_id_arr) == 1)
                $categories['data'][] = AlibabacategoryService::getInstance()->getOne(implode('', $category_id_arr));
            else if (count($category_id_arr) > 1)
                $categories = AlibabacategoryService::getInstance()->getList(1, count($category_id_arr), 'desc', 'id',
                    ['groupOp' => 'AND', 'rules' => [
                        ['field' => 'category_id', 'op' => 'in', 'data' => implode(',', $category_id_arr)]]]);

            $categories_name_id_arr = array_column($categories['data'], 'name', 'id');
        } catch (\Exception $e) {
        } finally {
            foreach ($module_list['data'] as $idx => $module) {
                $module_list['data'][$idx]['category_name'] = isset($categories_name_id_arr[$module['category_id']]) ?
                    $categories_name_id_arr[$module['category_id']] : '';
            }

            return $module_list;
        }
    }

    /**
     * 编辑1688商品分类 不可修改id
     * @param array $parameters
     * @return array|mixed|null
     * @throws AlibabacategoryException
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function editAlibabaCategory($parameters = []) {
        if (! isset($parameters['id']) || empty($parameters['id']))
            throw new AlibabacategoryException(AlibabacategoryException::ALIBABACATEGORY_ID_IS_EMPTY, AlibabacategoryException::ALIBABACATEGORY_ID_IS_EMPTY_NO);

        $update_arr = [];
        if (isset($parameters['name']))
            $update_arr['name'] = str_replace(['|', '-'], ['', ''], $parameters['name']);
        if (isset($parameters['parent']))
            $update_arr['parent'] = $parameters['parent'];
        if (isset($parameters['publishing']))
            $update_arr['publishing'] = $parameters['publishing'];
        if (isset($parameters['stats']))
            $update_arr['stats'] = $parameters['stats'];
        if (isset($parameters['listorder']))
            $update_arr['listorder'] = $parameters['listorder'];
        if (isset($parameters['parent'])) {
            try {
                $parent = AlibabacategoryService::getInstance()->getOne($parameters['parent']);
                if ($parent['publishing'] != 0)
                    throw new AlibabacategoryException(AlibabacategoryException::ALIBABACATEGORY_INVALID_PARENT, AlibabacategoryException::ALIBABACATEGORY_INVALID_PARENT_NO);
            } catch (\Exception $e) {
                throw new AlibabacategoryException(AlibabacategoryException::ALIBABACATEGORY_IS_NOT_EXISTS, AlibabacategoryException::ALIBABACATEGORY_IS_NOT_EXISTS_NO);
            }
            $update_arr['parent'] = $parameters['parent'];
        }
        if (isset($parameters['icon'])) {
            $file = false;
            $file_path = 0;
            if (!empty($parameters['icon']) && strpos($parameters['icon'], Registry::get('config')['application']['host']) !== false) {
                $file = str_replace(Registry::get('config')['application']['host'], APP_PATH . '/public', $parameters['icon']);
                $file_path = str_replace(Registry::get('config')['application']['host'], '', $parameters['icon']);
            } else
                $file_path = 0;
            if ($file !== false && ! file_exists($file))
                throw new AlibabacategoryException(AlibabacategoryException::ALIBABACATEGORY_ICON_NOT_EXISTS, AlibabacategoryException::ALIBABACATEGORY_ICON_NOT_EXISTS_NO);

            $update_arr['icon'] = $file_path;
        }

        if (!empty($update_arr))
            $alibabacategory = AlibabacategoryService::getInstance()->update($update_arr, $parameters['id']);
        else
            $alibabacategory = AlibabacategoryService::getInstance()->getOne($parameters['id']);

        return $alibabacategory;
    }

    /**
     * @param array $parameters
     * @return array
     * @throws AlibabacategoryException
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function getAlibabaCategoryList($parameters = []) {

        try {
            $sql = "SELECT c1.`id`, c1.`name`, c1.`parent`, c2.`name` AS parent_name, c1.`publishing`, c1.`stats`, " .
                "c1.`min_order_quantity`, c1.`icon`, c1.`listorder`, c1.`created_at`, c1.`created_by`, c1.`updated_at`, c1.`updated_by`, ".
                "CONCAT(c1.`parent`, '-', c1.`id`) AS path ";

            $rules = $condition = $where_arr = [];
            if (isset($parameters['id'])) {
                array_push($where_arr, 'c1.`id` = "' . $parameters['id'] . '"');
                array_push($rules, ['field' => 'id', 'op' => 'eq', 'data' => $parameters['id']]);
            }

            if (isset($parameters['stats'])) {
                if ($parameters['stats'] == '999' && isset($parameters['from_api']) && $parameters['from_api'] === true) {
                    array_push($where_arr, 'c1.`stats` = 1');
                    array_push($rules, ['field' => 'id', 'op' => 'eq', 'data' => 1]);
                } else {
                    array_push($where_arr, 'c1.`stats` = "' . $parameters['stats'] . '"');
                    array_push($rules, ['field' => 'id', 'op' => 'eq', 'data' => $parameters['stats']]);
                }
            }

            if (isset($parameters['name'])) {
                array_push($where_arr, 'c1.`name` like "' . $parameters['name'] . '%"');
                array_push($rules, ['field' => 'name', 'op' => 'nc', 'data' => $parameters['name'] . '%']);
            }

            if (isset($parameters['parent'])) {
                array_push($where_arr, 'c1.`parent` = "' . $parameters['parent'] . '"');
                array_push($rules, ['field' => 'parent', 'op' => 'eq', 'data' => $parameters['parent']]);
            } else if (!isset($parameters['from_api']) || $parameters['from_api'] === false) {
                array_push($where_arr, 'c1.`parent` = "0"');
                array_push($rules, ['field' => 'parent', 'op' => 'eq', 'data' => 0]);
            }

            if (isset($parameters['publishing'])) {
                array_push($where_arr, 'c1.`publishing` = "' . $parameters['publishing'] . '"');
                array_push($rules, ['field' => 'publishing', 'op' => 'eq', 'data' => $parameters['publishing']]);
            }


            $sql .= "FROM `alibabacategory` as c1 LEFT JOIN `alibabacategory` AS c2 ON c1.`parent` = c2.`id`";

            /*if (!empty($rules))
                $condition = ['groupOp' => 'AND', 'rules' => $rules];

            $alibaba_category_list = AlibabacategoryService::getInstance()->getList(
                isset($parameters['page']) ? $parameters['page'] : 1,
                isset($parameters['page_size']) ? $parameters['page_size'] : 10,
                isset($parameters['sort']) ? $parameters['sort'] : 'desc',
                isset($parameters['order']) ? $parameters['order'] : 'id',
                $condition
            );*/

            if (!empty($where_arr))
                $sql .= " WHERE " . implode(' AND ', $where_arr);

//            \Yaf\Registry::get('db')->info('ddd: ' . $sql);

            $alibaba_category_model = AlibabacategoryModel::getInstance();
            $alibaba_category_model->page = isset($parameters['page']) ? $parameters['page'] : 1;
//            $alibaba_category_model->page_size = isset($parameters['page_size']) ? $parameters['page_size'] : 10;
            $alibaba_category_model->page_size = 10;
            $count = $alibaba_category_model->getCount(empty($rules) ? [] : ['groupOp' => 'AND', 'rules' => $rules]);
            $total = $count->fetchColumn();
            $alibaba_category_model->genMeta($total);

            if (isset($parameters['from_api']) && $parameters['from_api'] == true)
                $sql .= " ORDER BY c1.`listorder` DESC";
            else
                $sql .= " ORDER BY c1.`listorder` DESC";

            $sql .= ($parameters['page'] === 0 && $parameters['page_size'] === 0 ? " LIMIT 1" : " LIMIT " . (($parameters['page'] - 1) * $parameters['page_size']) . ', ' . $parameters['page_size']);
            $result = $alibaba_category_model->query($sql);
            $alibaba_category_model->setModelProperty($result, true);
            $alibaba_category_list = [
                'data' => $alibaba_category_model->data,
                'meta' => $alibaba_category_model->meta
            ];

            $alibaba_category_list = User::getUsersByModule($alibaba_category_list);
            $parent_id_arr = array_column($alibaba_category_list['data'], 'id');

            foreach ($alibaba_category_list['data'] as $idx => $row) {
                $alibaba_category_list['data'][$idx]['icon'] = ! empty($row['icon']) ? Registry::get('config')['application']['host'] . $row['icon'] : $row['icon'];
                if (in_array($row['parent'], $parent_id_arr)) {
                    if (false !== $parent_key = array_search($row['parent'], $parent_id_arr)) {
                        $parent_path = $alibaba_category_list['data'][$parent_key]['path'] . '-' . $row['id'];
                    } else {
                        $parent_path = $parent_id_arr[$row['parent']] . '-' . $row['id'];
                    }
                } else {
                    $parent_path = $row['path'];
                }
                $alibaba_category_list['data'][$idx]['path'] = $parent_path;

                if (! isset($parameters['from_api']) || $parameters['from_api'] === false) {
                    $route = explode('-', $alibaba_category_list['data'][$idx]['path']);
                    if (count($route) >= 3) {
                        $prefix = '|';
                        for ($i = 1; $i < count($route); $i++) {
                            $prefix .= '--';
                        }
                    } else
                        $prefix = '|--';
                    $alibaba_category_list['data'][$idx]['name'] = $prefix . $row['name'];
                }
            }

//            if (! isset($parameters['from_api']) || $parameters['from_api'] !== true)
//                array_multisort(array_column($alibaba_category_list['data'], 'path'), SORT_ASC, $alibaba_category_list['data']);

            return $alibaba_category_list;
        } catch (ModelDriverException $e) {
            throw $e;
        } catch (ModelException $e) {
            if ($e->getCode() == ModelException::DATA_NOT_EXISTS)
                throw new AlibabacategoryException(AlibabacategoryException::ALIBABACATEGORY_IS_NOT_EXISTS, AlibabacategoryException::ALIBABACATEGORY_IS_NOT_EXISTS_NO);
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }

    }

}
